#ifndef SEMAPHORE_H_
#define SEMAPHORE_H_
 
 /*
  * 目前发现信号量在32位的系统上有问题，
  * 休眠的线程无法被正常唤醒，先禁用之
  */
 
 #include <mutex>
 #include <condition_variable>
 #include <chrono>
 #include <optional>
 
 namespace toolkit {
 
 /**
  * @brief 信号量类
  */
 class Semaphore {
 public:
     /**
      * @brief 构造函数
      * @param initial 初始信号量计数
      */
     explicit Semaphore(size_t initial = 0) : _count(initial) {
     }
 
     /**
      * @brief 析构函数
      */
     ~Semaphore() = default;
 
     /**
      * @brief 增加信号量
      * @param n 增加的数量
      */
     void post(size_t n = 1) {
         std::unique_lock<std::mutex> lock(_mutex);
         _count += n;
         if (n == 1) {
             _condition.notify_one();
         } else {
             _condition.notify_all();
         }
     }
 
     /**
      * @brief 等待并减少信号量
      */
     void wait() {
         std::unique_lock<std::mutex> lock(_mutex);
         _condition.wait(lock, [this]() { return _count > 0; });
         --_count;
     }
 
     /**
      * @brief 尝试等待并减少信号量
      * @return 是否成功获取信号量
      */
     bool tryWait() {
         std::unique_lock<std::mutex> lock(_mutex);
         if (_count > 0) {
             --_count;
             return true;
         }
         return false;
     }
 
     /**
      * @brief 带超时的等待
      * @param timeout 超时时间
      * @return 是否成功获取信号量
      */
     template<typename Rep, typename Period>
     bool waitFor(const std::chrono::duration<Rep, Period>& timeout) {
         std::unique_lock<std::mutex> lock(_mutex);
         if (!_condition.wait_for(lock, timeout, [this]() { return _count > 0; })) {
             return false;
         }
         --_count;
         return true;
     }
 
     /**
      * @brief 获取当前信号量计数
      * @return 当前计数值
      */
     size_t getValue() const {
         std::unique_lock<std::mutex> lock(_mutex);
         return _count;
     }
 
 private:
     size_t _count;
     mutable std::mutex _mutex;
     std::condition_variable _condition;
 };
 
 } /* namespace toolkit */
 #endif /* SEMAPHORE_H_ */